/**
 * 模块管理器实现
 * 动态模块加载系统的核心管理类
 */
import type { 
  DynamicModule, 
  ModuleLoadState, 
  ModuleRegistrationOptions,
  ModuleLoadOptions,
  ModuleUnloadOptions,
  ModuleConfig,
  ModulePerformanceMetrics,
  ModuleErrorInfo
} from './types'
import { EventEmitter } from './EventEmitter'
import { moduleLoader } from './ModuleLoader'
import { moduleStorage } from './ModuleStorage'

export class ModuleManager {
  private static instance: ModuleManager
  private moduleRegistry = new Map<string, DynamicModule>()
  private loadStates = new Map<string, ModuleLoadState>()
  private eventEmitter = new EventEmitter()
  private performanceMetrics = new Map<string, ModulePerformanceMetrics>()
  private errorHistory = new Map<string, ModuleErrorInfo[]>()
  private dependencyGraph = new Map<string, Set<string>>()

  private constructor() {
    // 初始化事件监听
    this.setupEventListeners()
  }

  static getInstance(): ModuleManager {
    if (!ModuleManager.instance) {
      ModuleManager.instance = new ModuleManager()
    }
    return ModuleManager.instance
  }

  /**
   * 注册模块
   */
  async registerModule(module: DynamicModule, options: ModuleRegistrationOptions = {}): Promise<void> {
    const {
      autoLoadDependencies = true,
      preload = false,
      timeout = 30000,
      maxRetries = 3
    } = options

    // 验证模块
    const validation = await moduleLoader.validate(module)
    if (!validation.isValid) {
      throw new Error(`Module validation failed: ${validation.errors.join(', ')}`)
    }

    // 检查是否已注册
    if (this.moduleRegistry.has(module.id)) {
      console.warn(`[ModuleManager] Module ${module.id} is already registered`)
      return
    }

    // 注册模块
    this.moduleRegistry.set(module.id, module)
    this.loadStates.set(module.id, {
      id: module.id,
      status: 'unloaded'
    })

    // 构建依赖图
    this.buildDependencyGraph(module)

    // 发射注册事件
    this.eventEmitter.emit('module:registered', module.id, module)

    console.log(`[ModuleManager] Module ${module.id} registered successfully`)

    // 如果需要预加载
    if (preload) {
      this.loadModule(module.id, { timeout, maxRetries }).catch(error => {
        console.error(`[ModuleManager] Failed to preload module ${module.id}:`, error)
      })
    }

    // 如果需要自动加载依赖
    if (autoLoadDependencies && module.dependencies) {
      for (const depId of module.dependencies) {
        if (this.moduleRegistry.has(depId)) {
          this.loadModule(depId, { timeout, maxRetries }).catch(error => {
            console.error(`[ModuleManager] Failed to load dependency ${depId} for ${module.id}:`, error)
          })
        }
      }
    }
  }

  /**
   * 加载模块
   */
  async loadModule(moduleId: string, options: ModuleLoadOptions = {}): Promise<any> {
    const module = this.moduleRegistry.get(moduleId)
    if (!module) {
      throw new Error(`Module ${moduleId} not found`)
    }

    const loadState = this.loadStates.get(moduleId)!
    
    // 如果已加载，直接返回
    if (loadState.status === 'loaded') {
      return loadState.component
    }

    // 如果正在加载，返回加载Promise
    if (loadState.status === 'loading') {
      // 这里需要实现等待逻辑
      return this.waitForModuleLoad(moduleId)
    }

    // 更新加载状态
    loadState.status = 'loading'
    loadState.retryCount = (loadState.retryCount || 0) + 1
    this.eventEmitter.emit('module:loading', moduleId)

    const startTime = Date.now()

    try {
      // 检查权限
      await this.checkModulePermissions(module)

      // 加载模块
      const component = await moduleLoader.load(module, options)

      // 更新加载状态
      loadState.status = 'loaded'
      loadState.component = component
      loadState.loadTime = Date.now() - startTime

      // 记录性能指标
      this.recordPerformanceMetrics(moduleId, loadState.loadTime)

      // 发射加载成功事件
      this.eventEmitter.emit('module:loaded', moduleId, component)

      console.log(`[ModuleManager] Module ${moduleId} loaded successfully in ${loadState.loadTime}ms`)

      return component

    } catch (error) {
      // 更新加载状态
      loadState.status = 'error'
      loadState.error = error instanceof Error ? error.message : 'Unknown error'

      // 记录错误信息
      this.recordError(moduleId, error)

      // 发射加载失败事件
      this.eventEmitter.emit('module:error', moduleId, error)

      console.error(`[ModuleManager] Failed to load module ${moduleId}:`, error)

      throw error
    }
  }

  /**
   * 卸载模块
   */
  async unloadModule(moduleId: string, options: ModuleUnloadOptions = {}): Promise<void> {
    const module = this.moduleRegistry.get(moduleId)
    if (!module) {
      throw new Error(`Module ${moduleId} not found`)
    }

    const loadState = this.loadStates.get(moduleId)
    if (!loadState || loadState.status === 'unloaded') {
      return
    }

    try {
      // 卸载模块
      await moduleLoader.unload(module, options)

      // 更新加载状态
      loadState.status = 'unloaded'
      loadState.component = undefined
      loadState.error = undefined

      // 清理性能指标
      this.performanceMetrics.delete(moduleId)

      // 发射卸载事件
      this.eventEmitter.emit('module:unloaded', moduleId)

      console.log(`[ModuleManager] Module ${moduleId} unloaded successfully`)

    } catch (error) {
      console.error(`[ModuleManager] Failed to unload module ${moduleId}:`, error)
      throw error
    }
  }

  /**
   * 获取模块状态
   */
  getModuleState(moduleId: string): ModuleLoadState | undefined {
    return this.loadStates.get(moduleId)
  }

  /**
   * 获取模块信息
   */
  getModule(moduleId: string): DynamicModule | undefined {
    return this.moduleRegistry.get(moduleId)
  }

  /**
   * 获取所有已注册的模块
   */
  getAllModules(): DynamicModule[] {
    return Array.from(this.moduleRegistry.values())
  }

  /**
   * 获取已加载的模块
   */
  getLoadedModules(): DynamicModule[] {
    return Array.from(this.moduleRegistry.values()).filter(module => {
      const state = this.loadStates.get(module.id)
      return state?.status === 'loaded'
    })
  }

  /**
   * 检查模块是否已加载
   */
  isModuleLoaded(moduleId: string): boolean {
    const state = this.loadStates.get(moduleId)
    return state?.status === 'loaded'
  }

  /**
   * 获取模块性能指标
   */
  getPerformanceMetrics(moduleId: string): ModulePerformanceMetrics | undefined {
    return this.performanceMetrics.get(moduleId)
  }

  /**
   * 获取所有性能指标
   */
  getAllPerformanceMetrics(): ModulePerformanceMetrics[] {
    return Array.from(this.performanceMetrics.values())
  }

  /**
   * 获取模块错误历史
   */
  getErrorHistory(moduleId: string): ModuleErrorInfo[] {
    return this.errorHistory.get(moduleId) || []
  }

  /**
   * 获取所有错误历史
   */
  getAllErrorHistory(): ModuleErrorInfo[] {
    const allErrors: ModuleErrorInfo[] = []
    this.errorHistory.forEach(errors => {
      allErrors.push(...errors)
    })
    return allErrors.sort((a, b) => b.timestamp - a.timestamp)
  }

  /**
   * 批量加载模块
   */
  async loadModules(moduleIds: string[], options: ModuleLoadOptions = {}): Promise<void> {
    // 按依赖关系排序
    const sortedIds = this.topologicalSort(moduleIds)
    
    // 并行加载
    const loadPromises = sortedIds.map(moduleId => 
      this.loadModule(moduleId, options).catch(error => {
        console.error(`[ModuleManager] Failed to load module ${moduleId}:`, error)
      })
    )

    await Promise.all(loadPromises)
  }

  /**
   * 批量卸载模块
   */
  async unloadModules(moduleIds: string[], options: ModuleUnloadOptions = {}): Promise<void> {
    // 按反向依赖关系排序
    const sortedIds = this.topologicalSort(moduleIds).reverse()
    
    const unloadPromises = sortedIds.map(moduleId => 
      this.unloadModule(moduleId, options).catch(error => {
        console.error(`[ModuleManager] Failed to unload module ${moduleId}:`, error)
      })
    )

    await Promise.all(unloadPromises)
  }

  /**
   * 重新加载模块
   */
  async reloadModule(moduleId: string, options: ModuleLoadOptions = {}): Promise<any> {
    await this.unloadModule(moduleId, { clearCache: true })
    return this.loadModule(moduleId, { ...options, force: true })
  }

  /**
   * 注册事件监听器
   */
  on(event: string, handler: Function): void {
    this.eventEmitter.on(event as any, handler as any)
  }

  /**
   * 移除事件监听器
   */
  off(event: string, handler: Function): void {
    this.eventEmitter.off(event as any, handler as any)
  }

  /**
   * 获取系统统计信息
   */
  getSystemStats() {
    const totalModules = this.moduleRegistry.size
    const loadedModules = Array.from(this.loadStates.values()).filter(state => state.status === 'loaded').length
    const loadingModules = Array.from(this.loadStates.values()).filter(state => state.status === 'loading').length
    const errorModules = Array.from(this.loadStates.values()).filter(state => state.status === 'error').length

    const storageStats = moduleStorage.getStats()

    return {
      modules: {
        total: totalModules,
        loaded: loadedModules,
        loading: loadingModules,
        error: errorModules,
        unloaded: totalModules - loadedModules - loadingModules - errorModules
      },
      storage: storageStats,
      performance: {
        averageLoadTime: this.calculateAverageLoadTime(),
        totalErrors: this.getAllErrorHistory().length
      }
    }
  }

  /**
   * 清理系统
   */
  async cleanup(): Promise<void> {
    // 清理存储
    await moduleStorage.cleanup()
    
    // 清理过期的性能指标
    this.cleanupPerformanceMetrics()
    
    // 清理过期的错误历史
    this.cleanupErrorHistory()
    
    console.log('[ModuleManager] System cleanup completed')
  }

  /**
   * 销毁管理器
   */
  async destroy(): Promise<void> {
    // 卸载所有模块
    const allModuleIds = Array.from(this.moduleRegistry.keys())
    await this.unloadModules(allModuleIds, { clearCache: true })

    // 清理资源
    this.moduleRegistry.clear()
    this.loadStates.clear()
    this.performanceMetrics.clear()
    this.errorHistory.clear()
    this.dependencyGraph.clear()
    this.eventEmitter.removeAllListeners()

    // 销毁存储
    moduleStorage.destroy()

    console.log('[ModuleManager] ModuleManager destroyed')
  }

  /**
   * 私有方法：设置事件监听器
   */
  private setupEventListeners(): void {
    this.eventEmitter.on('module:loaded', (moduleId: string) => {
      // 模块加载成功后的处理
      this.handleModuleLoaded(moduleId)
    })

    this.eventEmitter.on('module:error', (moduleId: string, error: Error) => {
      // 模块加载失败后的处理
      this.handleModuleError(moduleId, error)
    })
  }

  /**
   * 私有方法：处理模块加载成功
   */
  private handleModuleLoaded(moduleId: string): void {
    const module = this.moduleRegistry.get(moduleId)
    if (module?.dependencies) {
      // 检查依赖是否都已加载
      const allDepsLoaded = module.dependencies.every(depId => this.isModuleLoaded(depId))
      if (!allDepsLoaded) {
        console.warn(`[ModuleManager] Some dependencies of module ${moduleId} are not loaded`)
      }
    }
  }

  /**
   * 私有方法：处理模块加载失败
   */
  private handleModuleError(moduleId: string, error: Error): void {
    // 可以在这里添加自动重试逻辑
    const loadState = this.loadStates.get(moduleId)
    if (loadState && (loadState.retryCount || 0) < 3) {
      console.log(`[ModuleManager] Scheduling retry for module ${moduleId}`)
      setTimeout(() => {
        this.loadModule(moduleId).catch(err => {
          console.error(`[ModuleManager] Retry failed for module ${moduleId}:`, err)
        })
      }, 5000)
    }
  }

  /**
   * 私有方法：检查模块权限
   */
  private async checkModulePermissions(module: DynamicModule): Promise<void> {
    if (module.permissions && module.permissions.length > 0) {
      // 这里需要集成实际的权限检查逻辑
      // 简化版本：假设用户有所有权限
      console.log(`[ModuleManager] Checking permissions for module ${module.id}:`, module.permissions)
    }
  }

  /**
   * 私有方法：等待模块加载完成
   */
  private async waitForModuleLoad(moduleId: string): Promise<any> {
    return new Promise((resolve, reject) => {
      const checkInterval = setInterval(() => {
        const state = this.loadStates.get(moduleId)
        if (state?.status === 'loaded') {
          clearInterval(checkInterval)
          resolve(state.component)
        } else if (state?.status === 'error') {
          clearInterval(checkInterval)
          reject(new Error(state.error || 'Module loading failed'))
        }
      }, 100)

      // 超时处理
      setTimeout(() => {
        clearInterval(checkInterval)
        reject(new Error('Module loading timeout'))
      }, 30000)
    })
  }

  /**
   * 私有方法：构建依赖图
   */
  private buildDependencyGraph(module: DynamicModule): void {
    this.dependencyGraph.set(module.id, new Set())

    if (module.dependencies) {
      for (const depId of module.dependencies) {
        this.dependencyGraph.get(module.id)!.add(depId)
      }
    }
  }

  /**
   * 私有方法：拓扑排序
   */
  private topologicalSort(moduleIds: string[]): string[] {
    const visited = new Set<string>()
    const visiting = new Set<string>()
    const result: string[] = []

    const visit = (moduleId: string) => {
      if (visited.has(moduleId)) return
      if (visiting.has(moduleId)) {
        console.warn(`[ModuleManager] Circular dependency detected involving ${moduleId}`)
        return
      }

      visiting.add(moduleId)

      const dependencies = this.dependencyGraph.get(moduleId)
      if (dependencies) {
        for (const depId of dependencies) {
          if (moduleIds.includes(depId)) {
            visit(depId)
          }
        }
      }

      visiting.delete(moduleId)
      visited.add(moduleId)
      result.push(moduleId)
    }

    for (const moduleId of moduleIds) {
      if (!visited.has(moduleId)) {
        visit(moduleId)
      }
    }

    return result
  }

  /**
   * 私有方法：记录性能指标
   */
  private recordPerformanceMetrics(moduleId: string, loadTime: number): void {
    const module = this.moduleRegistry.get(moduleId)
    const metrics: ModulePerformanceMetrics = {
      moduleId,
      loadTime,
      timestamp: Date.now(),
      dependencyCount: module?.dependencies?.length || 0,
      retryCount: this.loadStates.get(moduleId)?.retryCount || 0
    }

    this.performanceMetrics.set(moduleId, metrics)
  }

  /**
   * 私有方法：记录错误信息
   */
  private recordError(moduleId: string, error: any): void {
    const errorInfo: ModuleErrorInfo = {
      moduleId,
      errorType: error.constructor.name,
      errorMessage: error.message || 'Unknown error',
      timestamp: Date.now(),
      stack: error.stack,
      retryCount: this.loadStates.get(moduleId)?.retryCount || 0
    }

    if (!this.errorHistory.has(moduleId)) {
      this.errorHistory.set(moduleId, [])
    }
    this.errorHistory.get(moduleId)!.push(errorInfo)
  }

  /**
   * 私有方法：计算平均加载时间
   */
  private calculateAverageLoadTime(): number {
    const metrics = Array.from(this.performanceMetrics.values())
    if (metrics.length === 0) return 0
    const totalLoadTime = metrics.reduce((sum, metric) => sum + metric.loadTime, 0)
    return totalLoadTime / metrics.length
  }

  /**
   * 私有方法：清理性能指标
   */
  private cleanupPerformanceMetrics(): void {
    const now = Date.now()
    const expiredMetrics: string[] = []

    this.performanceMetrics.forEach((metrics, moduleId) => {
      if (now - metrics.timestamp > 24 * 60 * 60 * 1000) { // 24小时
        expiredMetrics.push(moduleId)
      }
    })

    expiredMetrics.forEach(moduleId => {
      this.performanceMetrics.delete(moduleId)
    })
  }

  /**
   * 私有方法：清理错误历史
   */
  private cleanupErrorHistory(): void {
    const now = Date.now()
    const oneWeekAgo = now - 7 * 24 * 60 * 60 * 1000

    this.errorHistory.forEach((errors, moduleId) => {
      const recentErrors = errors.filter(error => error.timestamp > oneWeekAgo)
      if (recentErrors.length === 0) {
        this.errorHistory.delete(moduleId)
      } else {
        this.errorHistory.set(moduleId, recentErrors)
      }
    })
  }
}

// 创建全局管理器实例
export const moduleManager = ModuleManager.getInstance()
